#pragma once

#include <memory>
#include "SharedMemory.h"
#include "DesktopCaptureFrameQueue.h"
#include "ScopedThreadDesktop.h"
#include "DisplayConfigurationMonitor.h"
#include "desktop_capture_types.h"


class DesktopCaptureOptions;
class DesktopFrame;

class DesktopCapturer {
public:
	enum class Result {
		SUCCESS,

		ERROR_TEMPORARY,

		ERROR_PERMANENT,

		MAX_VALUE = ERROR_PERMANENT
	};

	class Callback {
	public:
		virtual void OnCaptureResult(Result result,
			std::unique_ptr<DesktopFrame> frame) = 0;

	protected:
		virtual ~Callback() {}
	};

	typedef intptr_t SourceId;

	static_assert(std::is_same<SourceId, ScreenId>::value,
		"SourceId should be a same type as ScreenId.");

	struct Source {
		SourceId id;

		std::string title;
	};

	typedef std::vector<Source> SourceList;

	virtual ~DesktopCapturer();

	virtual void Start(Callback* callback) = 0;

	virtual void SetSharedMemoryFactory(
		std::unique_ptr<SharedMemoryFactory> shared_memory_factory);

	virtual void CaptureFrame() = 0;

	virtual void SetExcludedWindow(WindowId window);

	virtual bool GetSourceList(SourceList* sources);

	virtual bool SelectSource(SourceId id);

	virtual bool FocusOnSelectedSource();

	virtual bool IsOccluded(const DesktopVector& pos);
};

